當有個方法,他處理眾多的欄位、函數來自於別的class, 這方法稱之為feature envy.
假設有位富人, 聘請一位僕人做家事, 準備邀請客人來家裡.
此時會有這兩個class:
public class Servant
{
private bool _isFloorSwept = false;
private bool _areDishesWashed = false;
private bool _isLaundryDone = false;
public void SweepFloor()
{
_isFloorSwept = true;
}
public void WashDishes()
{
_areDishesWashed = true;
}
public void DoLaundry()
{
_isLaundryDone = true;
}
public bool AreChoresDone()
{
return _isFloorSwept && _areDishesWashed;
}
}
public class Master
{
private Servant _servant;
public Master(Servant servant)
{
_servant = servant;
}
public void SweepFloor()
{
_servant.SweepFloor();
}
public void WashDishes()
{
_servant.WashDishes();
}
public void DoLaundry()
{
_servant.DoLaundry();
}
public bool AreChoresDone()
{
return _servant.AreChoresDone();
}
public bool IsReadyToInviteCustomer()
{
return AreChoresDone();
}
}
發現到, 主人的4種函數SweepFloor()
, WashDishes()
, DoLaundry()
, AreChoresDone()
, 都是僕人該做的.
因此, 我們可以將這4種函數從主人類別移除, 並修改IsReadyToInviteCustomer()
.
public class Master
{
private Servant _servant;
public Master(Servant servant)
{
_servant = servant;
}
public bool IsReadyToInviteCustomer()
{
return _servant.AreChoresDone();
}
}
經過這種重構, 使主人類別不再有僕人的功能, 保持主人與僕人各自的職責.
如果feature envy不處理, 容易導致高耦合的物件群. 日後要重構的時候, 得花時間做分離.
二來做測試時也很麻煩, 以重構前的Master為例, 得Mock Servant的各種行為才能測試完成.